import java.lang.Character;

import java.io.InputStreamReader;
import java.io.PushbackReader;
import java.util.List;
import java.util.ArrayList;

public class Lexer {
	/*
	 * Constructor
	 */
	public Lexer()
	{
		try
		{
			_ch = (char)System.in.read();
		}
		catch (Exception e)
		{
			System.out.println("Problem, officer?");
		}
		
		_reader = new PushbackReader(new InputStreamReader(System.in));
		
		_keywords = new ArrayList<String>();
		_commands = new ArrayList<String>();
		
		
		_keywords.add("while");
		_commands.add("quack");
		_commands.add("fly");
		_commands.add("left");
		_commands.add("right");
		_commands.add("up");
		_commands.add("down");
	}
	/*
	 * Returns next Lexeme
	 */
	public Lexeme Next()
	{
		String res = "";
		try
		{
			while (_ch == ' ')
			{
				_ch = (char)System.in.read();
			}
			if (_ch == '(')
			{
				_ch = (char)System.in.read();
				return new Lexeme(Token.Token_LPAREN,"(");
			}
			else if (_ch == ')')
			{
				_ch = (char)System.in.read();
				return new Lexeme(Token.Token_RPAREN,")");
			}
			else if (_ch == ';')
			{
				_ch = (char)System.in.read();
				return new Lexeme(Token.Token_SEMICOLON,";");
			}
			else if (_ch == ',')
			{
				_ch = (char)System.in.read();
				return new Lexeme(Token.Token_COMMA,",");
			}
			else if (_ch == '\"')
			{	
				_ch = (char)System.in.read();
				while (_ch != '\"')
				{
					res += _ch;
					_ch = (char)System.in.read();
				}
				_ch = (char)System.in.read();
				return new Lexeme(Token.Token_STRING,res);
			}
			else if (Character.isLetter(_ch))
			{
				while (Character.isLetter(_ch))
				{
					res += _ch;
					
					_ch = (char)System.in.read();
				}
				if (_keywords.contains(res))
				{
					return new Lexeme(Token.Token_KEYWORD,res);
				}
				if (_commands.contains(res))
				{
					return new Lexeme(Token.Token_COMMAND,res);
				}
				return new Lexeme(Token.Token_IDENT,res);
			}
			else
			{			
				res += _ch;
				_ch = (char)System.in.read();
				return new Lexeme(Token.Token_UNDEF,res);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		return new Lexeme(Token.Token_EOF,"");
	}
	
	
	private char _ch;
	PushbackReader _reader;
	private List<String> _keywords;
	private List<String> _commands;
}
